package com.gobang.service.impl;

import com.gobang.common.exception.GameException;
import com.gobang.common.util.GameRoomIdGenerator;
import com.gobang.common.util.MessageUtils;
import com.gobang.domain.dto.SurrenderRequestDTO;
import com.gobang.domain.entity.GameRoom;
import com.gobang.domain.enums.GameStatus;
import com.gobang.domain.enums.PlayerColor;
import com.gobang.domain.message.GameOverMessage;
import com.gobang.domain.vo.SurrenderResponseVO;
import com.gobang.domain.vo.UserInfoVO;
import com.gobang.mapper.GameRoomMapper;
import com.gobang.service.*;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Map;

/**
 * 游戏房间服务实现类
 * 提供游戏房间的创建和管理功能
 * 
 * @author System
 * @since 1.0.0
 */
@Service
@RequiredArgsConstructor
@Transactional
public class GameRoomServiceImpl implements GameRoomService {

    private static final Logger log = LoggerFactory.getLogger(GameRoomServiceImpl.class);

    private final GameRoomMapper gameRoomMapper;
    private final GameEngine gameEngine;
    //private final MatchSystemService matchSystemService;
    private final ConnectionManagerService connectionManagerService;
    private final MessageService messageService;
    private final StringRedisTemplate redisTemplate;
    private final UserService userService;
    private final NewGameService gameService;

    @Override
    public String createGameRoom(Long blackPlayerId, Long whitePlayerId) {
        log.info("创建游戏房间，黑方: {}, 白方: {}", blackPlayerId, whitePlayerId);
        
        try {
            // 生成房间ID
            String roomId = GameRoomIdGenerator.generateRoomId();
            
            // 创建房间实体: 当前只是匹配成功，创建房间，游戏并未开始。
            GameRoom gameRoom = new GameRoom();
            gameRoom.setId(roomId);
            gameRoom.setBlackPlayerId(blackPlayerId);
            gameRoom.setWhitePlayerId(whitePlayerId);
            gameRoom.setCurrentTurn(PlayerColor.BLACK.getCode());
            gameRoom.setGameStatus(GameStatus.WAITING.getCode());
            gameRoom.setTotalMoves(0);
            gameRoom.setCreatedAt(LocalDateTime.now());
            
            // 保存到数据库
            gameRoomMapper.insert(gameRoom);
            
            // 初始化游戏引擎状态
            gameEngine.initializeGame(roomId, blackPlayerId, whitePlayerId);
            
            // 更新用户状态为游戏中
            connectionManagerService.updateUserStatus(blackPlayerId, "gaming");
            connectionManagerService.updateUserStatus(whitePlayerId, "gaming");
            //matchSystemService.updateUserStatus(blackPlayerId, "gaming", roomId);
            //matchSystemService.updateUserStatus(whitePlayerId, "gaming", roomId);
            
            // 自动开始游戏
            gameEngine.startGame(roomId);
            gameRoomMapper.startGame(roomId);

            // message 发送游戏更新状态
//            GameStateUpdateMessage message = MessageUtils.createGameStateUpdateMessage();
//            messageService.sendGameStateUpdate(roomId, message);

            log.info("游戏房间创建成功，roomId: {}", roomId);
            return roomId;
            
        } catch (Exception e) {
            log.error("创建游戏房间失败，黑方: {}, 白方: {}", blackPlayerId, whitePlayerId, e);
            throw GameException.gameRoomNotFound();
        }
    }

//    @Override
//    public void cancelGameRoom(String roomId, String reason) {
//        log.info("取消游戏房间，roomId: {}, reason: {}", roomId, reason);
//
//        try {
//            // 取消游戏引擎中的游戏
//            gameEngine.cancelGame(roomId, reason);
//
//            // 更新数据库状态
//            gameRoomMapper.updateGameStatus(roomId, GameStatus.CANCELLED.getCode());
//
//            // 获取房间信息
//            GameRoom gameRoom = gameRoomMapper.findByRoomId(roomId);
//            if (gameRoom != null) {
//                // 更新用户状态为在线
//                matchSystemService.updateUserStatus(gameRoom.getBlackPlayerId(), "online", null);
//                matchSystemService.updateUserStatus(gameRoom.getWhitePlayerId(), "online", null);
//            }
//
//            log.info("游戏房间取消成功，roomId: {}", roomId);
//
//        } catch (Exception e) {
//            log.error("取消游戏房间失败，roomId: {}", roomId, e);
//            throw GameException.gameRoomNotFound();
//        }
//    }

    @Override
    public RoomCreationResult createRoom(Long blackPlayerId, Long whitePlayerId) {
        log.info("创建游戏房间（兼容方法），黑方: {}, 白方: {}", blackPlayerId, whitePlayerId);
        
        try {
            String roomId = createGameRoom(blackPlayerId, whitePlayerId);
            return RoomCreationResult.success(roomId);
            
        } catch (Exception e) {
            log.error("创建游戏房间失败", e);
            return RoomCreationResult.failure("创建房间失败：" + e.getMessage());
        }
    }

    @Override
    public SurrenderResponseVO surrender(SurrenderRequestDTO request) {
        log.info("处理认输请求，request: {}", request);

        String roomId = request.getRoomId();
        Long userId = request.getUserId();

        try {
            // 获取房间状态
            String roomKey = "room:" + roomId;
            Map<Object, Object> roomData = redisTemplate.opsForHash().entries(roomKey);

            if (roomData.isEmpty()) {
                throw GameException.gameRoomNotFound();
            }

            String gameStatus = (String) roomData.get("game_status");
            if (!"PLAYING".equals(gameStatus)) {
                // 严格校验只有游戏中的用户才能认输
                throw GameException.gameNotStarted();
            }

            // 确定获胜者
            Long blackPlayerId = Long.valueOf((String) roomData.get("black_player_id"));
            Long whitePlayerId = Long.valueOf((String) roomData.get("white_player_id"));

            // 不能是非黑白用户认输
            if (!userId.equals(blackPlayerId) && !userId.equals(whitePlayerId)) {
                throw GameException.gamePlayerNotInRoom();
            }

            Long winnerId = userId.equals(blackPlayerId) ? whitePlayerId : blackPlayerId;

            // 结束游戏
            // 1. 处理积分变化
            gameService.handleGameEnd(roomId, winnerId, "SURRENDER");

            // 2. 通知房间用户游戏已结束
            UserInfoVO user = userService.getUserById(winnerId);
            GameOverMessage gameOverMsg = MessageUtils.createGameOverMessage(
                    roomId,
                    winnerId,
                    user.getUsername(),
                    "WIN",
                    5,
                    user.getCurrentScore(),
                    "SURRENDER"
            );
            messageService.sendGameOverNotification(roomId, gameOverMsg);

            // 获取获胜者信息
            UserInfoVO winner = userService.getUserById(winnerId);

            return SurrenderResponseVO.builder()
                    .success(true)
                    .winnerId(winnerId)
                    .winnerUsername(winner.getUsername())
                    .gameStatus("FINISHED")
                    .build();

        } catch (Exception e) {
            log.error("认输处理失败", e);
            return SurrenderResponseVO.builder()
                    .success(false)
                    .errorMessage("认输失败：" + e.getMessage())
                    .build();
        }
    }



} 